using System;
using System.Threading;
using System.IO;
using System.Collections;

class MainClass
{
	static public void Main(){
		//inductiveLearning();
		DeductiveMain.deductiveLearning();
	}
	
	
	static void inductiveLearning(){
		//intMap();

		permutMap();
		//listMap();
	}

	static void permutMap(){
		PermutMapper m = new PermutMapper();
		m.addMapping("abcde","bacde");
		m.addMapping("abcdefg","bacdefg");
		assert("bacdefghi", m.map("abcdefghi")); // test swap #1 and #0 elements
		Console.WriteLine("=== first permutMap() test done");

		PermutMapper m1 = new PermutMapper();
		m1.addMapping("abcde","ebcda");
		m1.addMapping("abcdefg","ebcdafg");
		assert("ebcdafghi", m1.map("abcdefghi")); // test swap #0 and #4 elements

		PermutMapper m2 = new PermutMapper();
		m2.addMapping("abc","cba");
		m2.addMapping("abcde","ebcda");
		m2.addMapping("abcdefg","gbcdefa");
		assert("ibcdefgha", m2.map("abcdefghi")); // test swap #0 and LAST elements

		PermutMapper m3 = new PermutMapper();
		m3.addMapping("abc","abc");
		m3.addMapping("abcde","abedc");
		m3.addMapping("abcdefg","abgdefc");
		assert("abidefghc", m3.map("abcdefghi")); // test swap #2 and LAST elements
	}

	static void listMap(){
		ListMapper m1 = new ListMapper();
		m1.addMapping("one","two");
		m1.addMapping("two","three");
		m1.addMapping("three","four");
		assert("three", m1.map("two")); // test full direct mapping

		ListMapper m11 = new ListMapper();
		m11.addMapping("bzaa","zbaa");
		m11.addMapping("abc","bca");
		m11.addMapping("a9bbcc","9abbcc");
		assert("as", m11.map("sa")); // test #1 <-> #2 transmutation

		ListMapper m2 = new ListMapper();
		m2.addMapping("bbaa","2211");
		m2.addMapping("abc","123");
		m2.addMapping("aabbcc","112233");
		assert("cba", m2.map("321")); // test element-wise mapping

		Console.WriteLine("Finished listMap()");
	}

	static void intMap(){
		IntMapper m0 = new IntMapper();
		m0.addMapping(7,504);
		assert(504, m0.map(12)); // test learn from single case

		IntMapper m01 = new IntMapper();
		m01.addMapping(17,17);
		assert(12, m01.map(12)); // test learn from single case - NOOP

		IntMapper m02 = new IntMapper();
		m02.addMapping(7,49);
		assert(25, m02.map(5)); // test learn from single case - existing sequence

		IntMapper m1 = new IntMapper();
		m1.addMapping(1,0);
		m1.addMapping(2,0);
		m1.addMapping(3,0);
		assert(0, m1,(5)); // test const
		m1.addMapping(6,1);
		assert(0, m1,(4)); // test const override recent memory
		assert(1, m1,(6)); // test const override recent memory
		m1.addMapping(7,1);
		assert(1, m1, 8); // test const 2 rules
		assert(0, m1.map(0)); // test const 2 rules - check old rule not broken

		IntMapper m2 = new IntMapper();
		m2.addMapping(2,1);
		m2.addMapping(3,2);
		m2.addMapping(4,3);
		assert(2, m2.map(3)); // test recent memory
		assert(0, m2.map(1)); // test plain asc

		Console.WriteLine("Finished intMap()");
	}

	static void assert(string mustBe, string actual){
		string msg = mustBe.Equals(actual) ? "OK" : "FAIL!!!!!!!!!!!!!!!!!!";
		msg += " mustBe=" + mustBe + " actual=" + actual;
		Console.WriteLine(msg);
	}
	static void assert(int mustBe, int actual){
		string msg = mustBe==actual ? "OK" : "FAIL!!!!!!!!!!!!!!!!!!!!!";
		msg += " mustBe=" + mustBe + " actual=" + actual;
		Console.WriteLine(msg);
	}

	static void assert(int mustBe, IntMapper m, int key){
		string msg = mustBe==m.map(key) ? "OK" : "FAIL!!!!!!!!!!!!!!!!!!!!!";
		msg += " mustBe=" + mustBe + " actual=" + m.map(key) + " key=" + key;
		Console.WriteLine(msg);
	}

}

